﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DeployGames.TweenEngine
{
    public class TweenManager
    {
        public static void setAutoRemove(IBaseTween _object, bool value)
        {
            _object.IsAutoRemoveEnabled = value;
        }

        public static void setAutoStart(IBaseTween _object, bool value)
        {
            _object.IsAutoStartEnabled = value;
        }

        private List<IBaseTween> objects = new List<IBaseTween>(20);
        private bool isPaused = false;

        public TweenManager add(IBaseTween _object)
        {
            if (!objects.Contains(_object)) objects.Add(_object);
            if (_object.IsAutoStartEnabled) _object.start();
            return this;
        }

        public bool containsTarget(Object target)
        {
            for (int i = 0, n = objects.Count; i < n; i++)
            {
                IBaseTween obj = objects[i];
                if (obj.containsTarget(target)) return true;
            }
            return false;
        }

        public bool containsTarget(Object target, int tweenType)
        {
            for (int i = 0, n = objects.Count; i < n; i++)
            {
                IBaseTween obj = objects[i];
                if (obj.containsTarget(target, tweenType)) return true;
            }
            return false;
        }

        public void killAll()
        {
            for (int i = 0, n = objects.Count; i < n; i++)
            {
                IBaseTween obj = objects[i];
                obj.kill();
            }
        }

        public void killTarget(Object target)
        {
            for (int i = 0, n = objects.Count; i < n; i++)
            {
                IBaseTween obj = objects[i];
                obj.killTarget(target);
            }
        }

        public void killTarget(Object target, int tweenType)
        {
            for (int i = 0, n = objects.Count; i < n; i++)
            {
                IBaseTween obj = objects[i];
                obj.killTarget(target, tweenType);
            }
        }

        public void ensureCapacity(int minCapacity)
        {
            objects.Capacity = minCapacity;
        }

        public void pause()
        {
            isPaused = true;
        }

        public void resume()
        {
            isPaused = false;
        }

        public void update(float delta)
        {
            for (int i = objects.Count - 1; i >= 0; i--)
            {
                IBaseTween obj = objects[i];
                if (obj.IsFinished() && obj.IsAutoRemoveEnabled)
                {
                    objects.RemoveAt(i);
                    obj.free();
                }
            }

            if (!isPaused)
            {
                if (delta >= 0)
                {
                    for (int i = 0, n = objects.Count; i < n; i++) objects[i].update(delta);
                }
                else
                {
                    for (int i = objects.Count - 1; i >= 0; i--) objects[i].update(delta);
                }
            }
        }

        public int size()
        {
            return objects.Count;
        }

        public int getRunningTweensCount()
        {
            return getTweensCount(objects);
        }

        public int getRunningTimelinesCount()
        {
            return getTimelinesCount(objects);
        }

        public List<IBaseTween> getObjects()
        {
            return objects;
        }

        private static int getTweensCount(List<IBaseTween> objs)
        {
            int cnt = 0;
            for (int i = 0, n = objs.Count; i < n; i++)
            {
                IBaseTween obj = objs[i];
                if (obj.GetType() == typeof(Timeline))
                {
                    cnt += 1;
                }
                else
                {
                    cnt += getTweensCount(((Timeline)obj).getChildren());
                }
            }
            return cnt;
        }

        private static int getTimelinesCount(List<IBaseTween> objs)
        {
            int cnt = 0;
            for (int i = 0, n = objs.Count; i < n; i++)
            {
                IBaseTween obj = objs[i];
                if (obj.GetType() == typeof(Timeline))
                {
                    cnt += 1 + getTimelinesCount(((Timeline)obj).getChildren());
                }
            }
            return cnt;
        }
    }
}
